package net.cyndeline.components.item

import scala.math.{min => lowest, max => highest}
import net.cyndeline.entitySystem.Component
import com.escalatesoft.subcut.inject.BindingModule
import com.escalatesoft.subcut.inject.Injectable
import net.cyndeline.Counter
import net.cyndeline.MinMaxCounter

/**
 * Used by anything that can have a number of charges on it.
 */
trait ChargeComponent extends Component {
  
  /** Returns the number of charges left. */
  def charges: Int
  
  /** 
   * Modifies the charge amount by some value. The final value cannot
   * go below 0 or above the maximum value.
   * @param amount Amount to modify the charges by. Can be both 
   * 			   negative and positive. 
   */
  def modify(amount: Int)
  
  /** What the max amount of charges is. */
  def max: Int
  
  /** 
   * Sets a new max amount and lowers the current charge amount
   * by the same.
   */
  def max_=(newMax: Int)
}

class Charge(implicit val bindingModule: BindingModule) extends ChargeComponent with Injectable {
  private val counter = injectOptional[Counter] getOrElse new MinMaxCounter()
  counter.max = 1

  override def charges = counter.value
  
  
  override def modify(amount: Int) {
    counter.set(highest(0, lowest(counter.value + amount, counter.max)))
  }
  
  override def max = counter.max
  
  override def max_=(newMax: Int) {
    counter.max = highest(1, newMax)
     counter.set(lowest(counter.value, counter.max))
  }
  
  override def copy = {
    val copy = new Charge()
    copy.max = max
    copy.modify(charges)
    copy
  }
}